﻿Namespace Controls
    Public Class WaterFallPanel
        Inherits Panel

        Public Sub New()
            ColumnCount = 2
            ReDim ColumnHeight(ColumnCount - 1)
            childwidth = 480 / ColumnCount
        End Sub

        Dim childwidth As Double
        Shared ColumnHeight() As Double
        Dim heightlist As New List(Of Double)

        Public Shared ColumnCountProperty As DependencyProperty = DependencyProperty.Register("WaterFallPanel",
                                                                                              GetType(Integer),
                                                                                              GetType(WaterFallPanel),
                                                                                              New PropertyMetadata(New PropertyChangedCallback(Sub(o, e)
                                                                                                                                                   ReDim ColumnHeight(CInt(e.NewValue) - 1)
                                                                                                                                                   If o Is Nothing OrElse e.NewValue = e.OldValue Then
                                                                                                                                                       Return
                                                                                                                                                   End If
                                                                                                                                                   o.SetValue(ColumnCountProperty, e.NewValue)
                                                                                                                                               End Sub)))

        Public Property ColumnCount As Integer
            Get
                Return GetValue(ColumnCountProperty)
            End Get
            Set(value As Integer)
                SetValue(ColumnCountProperty, value)
            End Set
        End Property

        Protected Overrides Function MeasureOverride(availableSize As Size) As Size
            Dim resultSize As New Size(0, 0)
            For i = 0 To Children.Count - 1
                Children(i).Measure(availableSize)
            Next
            For i = 0 To ColumnHeight.Count - 1
                ColumnHeight(i) = 0
            Next
            heightlist.Clear()
            For i = 0 To Children.Count - 1
                Dim minheight = ColumnHeight.Min
                Dim h = 0
                For h = 0 To ColumnHeight.Length - 1
                    If ColumnHeight(h) = minheight Then
                        Exit For
                    End If
                Next
                ColumnHeight(h) += Children(i).DesiredSize.Height

                heightlist.Add(ColumnHeight.Min)
            Next

            resultSize.Height = ColumnHeight.Max
            If Children.Count = 0 Then
                resultSize.Height = 0
                resultSize.Width = 480
            Else
                resultSize.Width = (Children.Count + 1) * Children(0).DesiredSize.Width
            End If

            Return resultSize
        End Function

        Protected Overrides Function ArrangeOverride(finalSize As Size) As Size
            For i = 0 To ColumnHeight.Count - 1
                ColumnHeight(i) = 0
            Next

            heightlist.Clear()
            For i = 0 To Children.Count - 1
                Dim minheight = ColumnHeight.Min
                Dim h = 0
                For h = 0 To ColumnHeight.Length - 1
                    If ColumnHeight(h) = minheight Then
                        Exit For
                    End If
                Next
                Children(i).Arrange(New Rect(New Point(Children(i).DesiredSize.Width * h, ColumnHeight(h)), Children(i).DesiredSize))
                ColumnHeight(h) += Children(i).DesiredSize.Height
                If h = 0 Then
                    If Children(i).DesiredSize.Width > childwidth Then
                        ColumnHeight(h + 1) += Children(i).DesiredSize.Height
                    End If
                End If
                heightlist.Add(ColumnHeight.Min)
            Next
            If Children.Count < ColumnCount Then
                finalSize.Width = childwidth * (Children.Count + 1)
            Else
                finalSize.Width = childwidth * (ColumnCount + 1)
            End If

            Return finalSize
        End Function

        Public Function GetItemHeight(item As Integer) As Double
            If item >= 0 AndAlso item < heightlist.Count Then
                Return heightlist(item)
            Else
                Return 0
            End If
        End Function
    End Class
End Namespace